package com.lzh.shijicloudstack.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CalculateTools {

    private static int INTERVAL_TIME = 30;
    private static int START_COUNT = 20;

    /**
     * 两个数字相加并且保留6位小数
     *
     * @param param1 String
     * @param param2 String
     * @return String/null
     * @author lym 2018-08-20
     */
    public static String PlusTwoStringParam(String param1, String param2) {
        if (param1 == null && param2 == null) {
            return null;
        }
        double sum = 0;
        DecimalFormat sixDf = new DecimalFormat("####0.000000");
        if (param1 != null) {
            sum = PlusTwoDouble(Double.valueOf(param1), sum);
        }
        if (param2 != null) {
            sum = PlusTwoDouble(Double.valueOf(param2), sum);
        }

        return sixDf.format(sum);
    }


    /**
     * 两个数字相加并且保留6位小数
     *
     * @param param1 String
     * @param param2 String
     * @param ratio  param2需要乘上一个系数才可以相加
     * @return String/null
     * @author lym 2018-08-20
     */
    public static String PlusTwoStringParamWithRatio(String param1, String param2, float ratio) {
        double sum = 0;
        DecimalFormat sixDf = new DecimalFormat("####0.000000");
        if (param1 != null) {
            sum = PlusTwoDouble(Double.valueOf(param1), sum);
        }
        if (param2 != null) {
            sum = PlusTwoDouble(Double.valueOf(param2) * ratio, sum);
        }
        if (sum > 0) {
            return sixDf.format(sum);
        }
        return null;
    }


    /**
     * 两个数字相加并且保留6位小数
     *
     * @param param1 String
     * @param param2 String
     * @return String/null
     * @author lym 2018-08-20
     */
    public static String PlusTwoStringParamNotNull(String param1, String param2) {
        double sum = 0;
        DecimalFormat sixDf = new DecimalFormat("####0.000000");
        if (param1 != null) {
            sum = PlusTwoDouble(Double.valueOf(param1), sum);
        }
        if (param2 != null) {
            sum = PlusTwoDouble(Double.valueOf(param2), sum);
        }
        if (sum > 0) {
            return sixDf.format(sum);
        }
        return "0";
    }

    /**
     * 两个数字相加并且保留6位小数
     *
     * @param param1 Double
     * @param param2 Double
     * @return Double/null
     * @author lym 2018-08-20
     */
    public static Double PlusTwoDoubleParam(Double param1, Double param2) {
        double sum = 0;
        if (param1 != null) {
            sum = PlusTwoDouble(param1, sum);
        }
        if (param2 != null) {
            sum = PlusTwoDouble(param2, sum);
        }
        if (sum > 0) {
            return sum;
        }
        return null;
    }

    /**
     * 两个数字相加并且保留6位小数
     *
     * @param param1 Float
     * @param param2 Float
     * @return Float/null
     * @author lym 2018-08-25
     */
    public static Float PlusTwoFloatParam(Float param1, Float param2) {
        float sum = 0;
        if (param1 != null) {
            sum = param1 + sum;
        }
        if (param2 != null) {
            sum = param2 + sum;
        }
        if (sum > 0) {
            return sum;
        }
        return null;
    }


    /**
     * 两个数字相加并且保留6位小数
     *
     * @param param1 Double
     * @param param2 Float
     * @return Double/null
     * @author lym 2018-08-25
     */
    public static Double PlusTwoDoubleAndFloatParam(Double param1, Float param2) {
        Double sum = 0.0;
        if (param1 != null) {
            sum = param1 + sum;
        }
        if (param2 != null) {
            sum = param2 + sum;
        }
        if (sum > 0) {
            return sum;
        }
        return null;
    }

    /**
     * 列表里面所有的数据相加
     *
     * @param list List<String>
     * @return String/null
     * @author lym 2018-08-22
     */
    public static String SUMList(List<String> list) {
        if (list == null) {
            return null;
        }
        String sum = null;
        for (String child : list) {
            sum = PlusTwoString(sum, child, 6);
        }
        return sum;
    }

    /**
     * 列表里面所有的数据相加
     *
     * @param list List<Double>
     * @return double
     * @author lym 2018-08-23
     */
    public static double SUMDoubleList(List<Double> list) {
        double sum = 0;
        for (Double child : list) {
            if (child != null) {
                sum = PlusTwoDouble(child, sum);
            }
        }
        return sum;
    }


    /**
     * 列表里面所有的数据相加
     *
     * @param list List<Float>
     * @return Float/null
     * @author lym 2018-08-23
     */
    public static Float SUMFloatList(List<Float> list) {
        Float sum = null;
        for (Float child : list) {
            if (child != null) {
                sum = PlusTwoFloatParam(sum, child);
            }
        }
        return sum;
    }

    /**
     * 列表里面所有的数据相加
     *
     * @param list List<Integer>
     * @return int
     * @author ycx 2019-04-29
     */
    public static int SUMIntList(List<Integer> list) {
        int sum = 0;
        for (Integer child : list) {
            if (child != null) {
                sum += child.intValue();
            }
        }
        return sum;
    }

    /**
     * 两个列表数据相加
     *
     * @param list1 List<String>
     * @param list2 List<String>
     * @return List<String>
     * @author lym 2018-08-24
     */
    public static List<String> SUMTwoStringList(List<String> list1, List<String> list2, int num) {
        if (list1 == null || list1.size() <= 0) {
            return list2;
        } else if (list2 == null || list2.size() <= 0) {
            return list1;
        }
        List<String> result = MyTools.initList(list1.size());
        for (int i = 0; i < list1.size(); i++) {
            String sum = PlusTwoString(list1.get(i), list2.get(i), num);
            if (sum != null) {
                result.set(i, sum);
            }
        }
        return result;
    }


    /**
     * 两个列表数据相加
     *
     * @param list1 List<Double>
     * @param list2 List<Double>
     * @return List<Double>
     * @author lym 2018-08-24
     */
    public static List<Double> SUMTwoDoubleList(List<Double> list1, List<Double> list2) {
        if ((list1 == null) && (list2 == null)) {
            return null;
        } else if (list1 == null) {
            return list2;
        } else if (list2 == null) {
            return list1;
        }
        List<Double> result = MyTools.initDoubleList(list1.size());
        for (int i = 0; i < list1.size(); i++) {
            Double sum = PlusTwoDoubleParam(list1.get(i), list2.get(i));
            if ((sum != null) && (sum > 0)) {
                result.set(i, sum);
            }
        }
        return result;
    }


    /**
     * 两个数字相乘并且保留6位小数
     *
     * @param param1 String
     * @param param2 String
     * @return String
     * @author lym 2018-08-20
     */
    public static String MultiplyTwoParam(String param1, String param2) {
        if (param1 != null && param2 != null) {
            BigDecimal a1 = new BigDecimal(param1).setScale(6, BigDecimal.ROUND_HALF_UP);
            BigDecimal b1 = new BigDecimal(param2).setScale(6, BigDecimal.ROUND_HALF_UP);
            return a1.multiply(b1).setScale(6, BigDecimal.ROUND_HALF_UP).toString();
        }
        return null;
    }


    /**
     * 两个数字相乘并且向下取整
     *
     * @param param1 :
     * @param param2 :
     * @return java.lang.String
     * @author ycx
     * @date 2020/10/12
     */
    public static String MultiplyTwoParamForPower(String param1, String param2) {
        if (param1 != null && param2 != null) {
            BigDecimal a1 = new BigDecimal(param1).setScale(6, BigDecimal.ROUND_HALF_UP);
            BigDecimal b1 = new BigDecimal(param2).setScale(6, BigDecimal.ROUND_HALF_UP);
            return a1.multiply(b1).setScale(0, BigDecimal.ROUND_FLOOR).toString();
        }
        return null;
    }

    /**
     * 计算收益
     *
     * @param energy     Double
     * @param price      Float
     * @param city_price Float
     * @param ratio      Float
     * @return Double
     * @author lym 2018-08-20
     */
    public static Double CalculateEarnings(Double energy, Float price, Float city_price, Float ratio) {
        if (energy != null && energy > 0) {
            DecimalFormat sixDf = new DecimalFormat("####0.000000");
            double result = energy * ratio / 100 * city_price + energy * (1 - ratio / 100) * price;
            return Double.valueOf(sixDf.format(result));
        } else {
            return null;
        }
    }

    /**
     * 计算PR值  返回结果保留4位小数
     *
     * @param E 测试周期内系统累计发电量   （按照业内标准，以电表检测数据为准精确度相对高一点，但是西门发电能量是各组串逆变器发电数据之和）
     * @param P 标称功率（也就是装机容量）（标准测试条件下）
     * @param H 测试周期内系统累计辐照量   但是是  MJ/m2   10^6 / 3600
     * @return Double
     * @author lym 2018-08-20
     */
    public static Double CalculatePR(Double E, Float P, Double H) {
        //标准测试条件下，是1000 w/m2
        int G = 1000;
        double PR = (E / P) / (H * 1000000 / 3600 / G);
        if (PR < 1) {
            BigDecimal a1 = new BigDecimal(PR).setScale(4, BigDecimal.ROUND_HALF_UP);
            return a1.doubleValue();
        }
        return 0.98;
    }

    /**
     * 预测发电量信息
     *
     * @param irradiation 辐照量
     * @param systemSize  装机容量
     * @param efficiency  系统效率   是乘上100之后的数据，所以处理时需要除100
     * @return Double
     * @author lym 2018-09-21
     */
    public static Double CalculateForecastValue(Float irradiation, Float systemSize, Float efficiency) {
        if (irradiation != null) {
            //标准测试条件下，是1000 w/m2   系统效率统一取79%
            int G = 1000;
            DecimalFormat sixDf = new DecimalFormat("####0.00");
            String forecastValue = sixDf.format((irradiation * 1000000 / 3600 / G) * systemSize * (efficiency / 100));
            return Double.valueOf(forecastValue);
        }
        return null;
    }

    /**
     * 预测发电量信息
     *
     * @param irradiation 辐照量
     * @param systemSize  装机容量
     * @param efficiency  系统效率   是乘上100之后的数据，所以处理时需要除100
     * @return Double
     * @author lym 2018-09-21
     */
    public static Double CalculateForecastValue2(Double irradiation, Float systemSize, Float efficiency) {
        if (irradiation != null) {
            //标准测试条件下，是1000 w/m2   系统效率统一取79%
            int G = 1000;
            DecimalFormat sixDf = new DecimalFormat("####0.00");
            String forecastValue = sixDf.format((irradiation * 1000000 / 3600 / G) * systemSize * (efficiency / 100));
            return Double.valueOf(forecastValue);
        }
        return null;
    }

    /**
     * 两个Double数据相减
     *
     * @param a Double
     * @param b Double
     * @return Double
     * @author lym 2018-12-28
     */
    public static Double SubtractionTwoDouble(Double a, Double b) {
        BigDecimal a1 = new BigDecimal(a + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.subtract(b1);
        return a1.doubleValue();
    }


    /**
     * 两个Double数据相加
     *
     * @param a Double
     * @param b Double
     * @return Double
     * @author lym 2018-12-28
     */
    public static Double PlusTwoDouble(Double a, Double b) {
        if (a == null) {
            a = 0.0;
        }
        if (b == null) {
            b = 0.0;
        }
        BigDecimal a1 = new BigDecimal(a + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.add(b1);
        return a1.doubleValue();
    }

    /**
     * 两个Double数据计算增长比例
     *
     * @param a Double
     * @param b Double
     * @return Double
     * @author lym 2019-02-13
     */
    public static Double AnalyseTwoDouble(Double a, Double b) {
        BigDecimal a1 = new BigDecimal(a + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.subtract(b1);
        a1 = a1.divide(b1, 4, RoundingMode.HALF_UP);
        return a1.doubleValue();
    }


    /**
     * 两个数据相除
     *
     * @param a   Double
     * @param b   Double
     * @param num 保留几位小数
     * @return Double
     * @author lym 2019-02-15
     */
    public static Double DivideTwoDouble(Double a, Double b, int num) {
        BigDecimal a1 = new BigDecimal(a + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.divide(b1, num, RoundingMode.HALF_UP);
        return a1.doubleValue();
    }

    /**
     * 两个数据相除
     *
     * @param a   String
     * @param b   String
     * @param num 保留几位小数
     * @return String/null
     * @author lym 2019-02-15
     */
    public static String DivideTwoString(String a, String b, int num) {
        if (a == null || b == null || "".equals(a) || "".equals(b) || Double.parseDouble(b) == 0) {
            return null;
        }
        BigDecimal a1 = new BigDecimal(a).setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b).setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.divide(b1, num, RoundingMode.HALF_UP);
        return a1.toPlainString();
    }

    /**
     * 两个数据相加
     *
     * @param a   String
     * @param b   String
     * @param num 保留几位小数
     * @return String/null
     * @author lym 2019-02-15
     */
    public static String PlusTwoString(String a, String b, int num) {
        if (a != null && !"".equals(a) && b != null && !"".equals(b)) {
            BigDecimal a1 = new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP);
            BigDecimal b1 = new BigDecimal(b).setScale(num, BigDecimal.ROUND_HALF_UP);
            a1 = a1.add(b1);
            return a1.toPlainString();
        }
        if (a != null) {
            return new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
        } else if (b != null) {
            return new BigDecimal(b).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
        } else {
            return null;
        }
    }

    /**
     * 两个数据相减
     *
     * @param a   String
     * @param b   String
     * @param num 保留几位小数
     * @return java.lang.String
     * @author ycx
     * @date 2020/9/22
     */
    public static String SubtractTwoString(String a, String b, int num) {
        if (a != null && !"".equals(a) && b != null && !"".equals(b)) {
            BigDecimal a1 = new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP);
            BigDecimal b1 = new BigDecimal(b).setScale(num, BigDecimal.ROUND_HALF_UP);
            a1 = a1.subtract(b1);
            return a1.toPlainString();
        } else if (a != null && !"".equals(a)) {
            return new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
        } else if (b != null && !"".equals(b)) {
            if (b.indexOf("-") == 0) {
                return new BigDecimal(b.substring(1)).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
            } else {
                return new BigDecimal("-" + b).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
            }
        } else {
            return null;
        }
    }

    /**
     * 两个数据相乘
     *
     * @param a   String
     * @param b   String
     * @param num 保留几位小数
     * @return java.lang.String
     * @author ycx
     * @date 2020/9/22
     */
    public static String MultiplyTwoString(String a, String b, int num) {
        if (a != null && !"".equals(a) && b != null && !"".equals(b)) {
            BigDecimal a1 = new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP);
            BigDecimal b1 = new BigDecimal(b).setScale(num, BigDecimal.ROUND_HALF_UP);
            a1 = a1.multiply(b1);
            return a1.setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
        } else if (a != null && !"".equals(a)) {
            return new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
        } else if (b != null && !"".equals(b)) {
            if (b.indexOf("-") == 0) {
                return new BigDecimal(b.substring(1)).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
            } else {
                return new BigDecimal("-" + b).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
            }
        } else {
            return null;
        }
    }

    /**
     * 将两个数字取平均
     *
     * @param a   : 1
     * @param b   : 2
     * @param num : 保留小数位
     * @return java.lang.String
     * @author ycx
     * @date 2020/5/28
     */
    public static String AverageTwoString(String a, String b, int num) {
        if (a == null || "".equals(a)) {
            return b;
        } else if (b == null || "".equals(b)) {
            return a;
        }
        BigDecimal a1 = new BigDecimal(a).setScale(num, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b).setScale(num, BigDecimal.ROUND_HALF_UP);
        a1 = a1.add(b1);
        a1 = a1.divide(new BigDecimal(2), BigDecimal.ROUND_HALF_UP);
        return String.valueOf(a1.doubleValue());
    }

    /**
     * 求平均
     *
     * @param a Double
     * @param b int
     * @return Double
     * @author lym 2019-02-15
     */
    public static Double AVGDouble(Double a, int b) {
        BigDecimal a1 = new BigDecimal(a + "").setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(b + "").setScale(1, BigDecimal.ROUND_HALF_UP);
        a1 = a1.divide(b1, 2, RoundingMode.HALF_UP);
        return a1.doubleValue();
    }

    /**
     * 将字符串数据转换成为Double类型 并且保留2位小数
     *
     * @param data String
     * @return Double
     * @author lym 2019-07-03
     */
    public static Double changeStringToDouble(String data) {
        BigDecimal a = new BigDecimal(data + "").setScale(2, BigDecimal.ROUND_HALF_UP);
        return a.doubleValue();
    }

    /**
     * 获取列表中的最大值
     *
     * @param list List<String>
     * @return StringgetDailyEnergyInPeriod
     * @author ycx 2019-07-03
     */
    public static String GetMaxInStringList(List<String> list) {
        if (list == null) {
            return null;
        }
        Double max = null;
        for (String num : list) {
            if (num != null) {
                if (max == null || Double.parseDouble(num) > max) {
                    max = Double.parseDouble(num);
                }
            }
        }
        if (max == null) {
            return null;
        }
        return Double.toString(max);
    }

    /**
     * 获取列表中的最大值的位置
     *
     * @param list List<String>
     * @return int
     * @author ycx 2019-07-03
     */
    public static int GetMaxIndexInStringList(List<String> list) {
        double max = 0.0;
        int maxIndex = 0;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) != null) {
                if (Double.parseDouble(list.get(i)) > max) {
                    max = Double.parseDouble(list.get(i));
                    maxIndex = i;
                }
            }
        }
        return maxIndex;
    }

    /**
     * 获取环保收益
     *
     * @param energy String
     * @return Map<String, String>
     * co2		二氧化碳
     * tree	树
     * light	灯
     * gas		汽油
     * @author ycx 2019-07-03
     */
    public static Map<String, String> GetEnvironmentalProtection(String energy) {
        if (energy == null) {
            return null;
        }
        Map<String, String> envPro = new HashMap<>();
        // 2024-01-26 hys 二氧化碳与树计算公式修改
        envPro.put("co2", MultiplyTwoString(energy, "0.997", 6));
        envPro.put("tree", MultiplyTwoString(energy, "0.037", 6));
        envPro.put("light", DivideTwoString(energy, "0.33", 6));
        envPro.put("gas", DivideTwoString(energy, "12", 6));
        return envPro;
    }

    /**
     * 获取列表中的大于零的非空个数
     *
     * @param list List<String>
     * @return int
     * @author ycx 2019-07-03
     */
    public static int CountNotNullAndNonZero(List<String> list) {
        if (list == null) {
            return 0;
        }
        int count = 0;

        for (String num : list) {
            if (num != null) {
                if (Double.parseDouble(num) != 0) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 获取列表中的非空个数
     *
     * @param list List<String>
     * @return int
     * @author ycx 2019-07-03
     */
    public static int CountNotNull(List<String> list) {
        if (list == null) {
            return 0;
        }
        int count = 0;

        for (String num : list) {
            if (num != null) {
                count++;
            }
        }

        return count;
    }

    /**
     * 判断是否为纯数字
     *
     * @param str String
     * @return boolean
     * @author ycx 2019-10-12
     */
    public static boolean IsNumber(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        return isNum.matches();
    }

    /**
     * 将视图中的能量统一乘以 proportion
     *
     * @param energy_list Map<String,List<String>>
     * @param proportion  Double
     * @return Map<String, List < String>>
     * @author ycx 2019-10-12
     */
    public static Map<String, List<String>> ViewEnergyRegulate(Map<String, List<String>> energy_list, Double proportion) {
        String proportionString = Double.toString(proportion);

        for (String key : energy_list.keySet()) {
            List<String> list = energy_list.get(key);
            for (int i = 0; i < list.size(); i++) {
                list.set(i, MultiplyTwoParam(list.get(i), proportionString));
            }
            energy_list.put(key, list);
        }

        return energy_list;
    }

    /**
     * 将列表中的数据统一乘以 proportion
     *
     * @param list       List<String>
     * @param proportion Double
     * @return List<String>
     * @author ycx 2019-10-14
     */
    public static List<String> ListDataRegulate(List<String> list, Double proportion) {
        String proportionString = Double.toString(proportion);

        for (int i = 0; i < list.size(); i++) {
            list.set(i, MultiplyTwoParam(list.get(i), proportionString));
        }

        return list;
    }


    /**
     * 将Map的数据统一乘以 proportion
     *
     * @param map        Map<String, String>
     * @param proportion Double
     * @return List<String>
     * @author lym 2021-02-02
     */
    public static Map<String, String> MapDataRegulate(Map<String, String> map, Double proportion) {
        String proportionString = Double.toString(proportion);

        for (String key : map.keySet()) {
            map.put(key, MultiplyTwoParam(map.get(key), proportionString));
        }

        return map;
    }

    /**
     * 将列表中的数据统一乘以比率 —— 功率用(向下取整)
     *
     * @param list       : 列表
     * @param proportion : 比率
     * @return java.util.List<java.lang.String>
     * @author ycx
     * @date 2020/10/12
     */
    public static List<String> ListDataRegulateForPower(List<String> list, Double proportion) {
        String proportionString = Double.toString(proportion);

        for (int i = 0; i < list.size(); i++) {
            list.set(i, MultiplyTwoParamForPower(list.get(i), proportionString));
        }

        return list;
    }

    /**
     * 将List<String> 转换成 List<Integer>
     *
     * @param list List<String>
     * @return List<Integer>
     * @author ycx 2019-10-23
     */
    public static List<Integer> TurnStringListToIntegerList(List<String> list) {
        List<Integer> result = new ArrayList<>();
        for (String num : list) {
            if (num != null && !"".equals(num)) {
                result.add(Integer.parseInt(num));
            } else {
                result.add(null);
            }
        }
        return result;
    }

    /**
     * 计算两个时间点之间跨越的小时数
     *
     * @param timeBefore 时间 HH:mm:ss
     * @param timeAfter  时间 HH:mm:ss
     * @return int
     * @author ycx 2019-11-27
     */
    public static int getHourBetweenTwoTime(String timeBefore, String timeAfter) {
        if (timeBefore == null || timeAfter == null) {
            return 0;
        }
        return Integer.parseInt(timeAfter.substring(0, 2)) - Integer.parseInt(timeBefore.substring(0, 2)) + 1;
    }

    /**
     * 将视图中的历史总能量统一乘以 proportion
     *
     * @param energyMap  Map<String,String>
     * @param proportion Double
     * @return Map<String, List < String>>
     * @author ycx 2020-03-13
     */
    public static void ViewLifeTimeEnergyRegulate(Map<String, String> energyMap, Double proportion) {
        String proportionString = Double.toString(proportion);
        energyMap.replaceAll((k, v) -> MultiplyTwoParam(energyMap.get(k), proportionString));
    }

    /**
     * 处理ECU实时数据补点问题
     *
     * @param flag   : 标志轴
     * @param time   : 时间轴
     * @param power  : 功率轴
     * @param energy : 能量轴
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author ycx
     * @date 2020/3/30
     */
    public static Map<String, Object> dealEcuCurrentDayDate(List<Integer> flag, List<Long> time, List<String> power, List<String> energy) {

        Map<String, Object> result = new HashMap<>();

        if (flag != null) {
            power = MyTools.checkECUPower(flag, power);
            energy = MyTools.checkECUPower(flag, energy);
        }

        /******************************** 补点加均分处理 *********************************/
//        int interval = getTimeInterval(time);
//
//        if(time.size() < START_COUNT){
//            result.put("time", time);
//            result.put("power", power);
//            result.put("energy", energy);
//            return result;
//        }
//
//        List<Long> newLongList = new ArrayList<>();
//        List<String> energyListResult = new ArrayList<>();
//        List<String> powerListResult = new ArrayList<>();
//
//        for (int i = 0; i < time.size() - 1; i++) {
//            int timeInterval = (int)((time.get(i + 1) - time.get(i)) / (60 * 1000)) / interval;
//            if (i < time.size() - 1 && timeInterval > 1 && timeInterval <= Math.floor(INTERVAL_TIME / interval)) {
//                newLongList.add(time.get(i));
//                powerListResult.add(power.get(i));
//                energyListResult.add(energy.get(i) );
//                for (int j = 1; j < timeInterval; j++) {
//                    newLongList.add(time.get(i) + j * interval * 60 * 1000);
//                    powerListResult.add(power.get(i + 1));
//                    energyListResult.add("0.0");
//                }
//            } else {
//                newLongList.add(time.get(i));
//                powerListResult.add(power.get(i));
//                energyListResult.add(energy.get(i));
//            }
//        }
//        newLongList.add(time.get(time.size() - 1));
//        powerListResult.add(power.get(time.size() - 1));
//        energyListResult.add(energy.get(time.size() - 1));
//
//        for (int i = 0; i < energyListResult.size(); i++) {
//            if (energyListResult.get(i) == null || Double.parseDouble(energyListResult.get(i)) == 0) {
//                int nullCount = getNullCountDouble(energyListResult, i);
//                String sumPower = SUMList(powerListResult.subList(i, i + nullCount + 1));
//                if (sumPower != null && Double.parseDouble(sumPower) != 0) {
//                    for (int j = 0; j < nullCount + 1; j++) {
//                        energyListResult.set(i + j, MultiplyTwoParam(energyListResult.get(i + nullCount), DivideTwoString(powerListResult.get(i + j), sumPower, 6)));
//                    }
//                } else {
//                    for (int j = 0; j < nullCount + 1; j++) {
//                        energyListResult.set(i + j, DivideTwoString(energyListResult.get(i + nullCount), Integer.toString(nullCount + 1), 6));
//                    }
//                }
//                i += nullCount;
//            }
//        }
//
//        result.put("time", newLongList);
//        result.put("power", powerListResult);
//        result.put("energy", energyListResult);
//        return result;


        /********************************* 能量按照功率平均分处理 *********************************/

        String sumPower = SUMList(power);
        List<String> energyListResult = new ArrayList<>();
        if (sumPower != null && Double.parseDouble(sumPower) > 0) {
            String sumEnergy = SUMList(energy);

            for (String p : power) {
                energyListResult.add(MultiplyTwoParam(sumEnergy, DivideTwoString(p, sumPower, 6)));
            }
        }
        result.put("time", time != null ? time : new ArrayList<Long>());
        result.put("power", power);
        result.put("energy", energyListResult);
        result.put("F", flag != null ? flag : new ArrayList<Integer>());
        return result;

    }

    /**
     * 获取实点间的时间间隔 —— 无法得出默认返回5分钟
     *
     * @param longList : 时间列表
     * @return int
     * @author ycx
     * @date 2020/3/30
     */
    private static int getTimeInterval(List<Long> longList) {
        for (int i = 0; i < longList.size() - 1; i++) {
            if ((longList.get(i + 1) - longList.get(i)) / (60 * 1000) < 20) {
                return ((longList.get(i + 1) - longList.get(i)) / (60 * 1000)) % 4 == 0 ? 4 : 5;
            }
        }
        return 5;
    }

    /**
     * 获取为下一个实点钱的为0数
     *
     * @param list  : 列表
     * @param first : 第一个位置
     * @return int
     * @author ycx
     * @date 2020/3/30
     */
    private static int getNullCountDouble(List<String> list, int first) {
        boolean hasData = false;
        int count = 0;
        for (int i = first; i < list.size(); i++) {
            if (list.get(i) != null && Double.parseDouble(list.get(i)) == 0) {
                count++;
            } else {
                hasData = true;
                break;
            }
        }
        if (hasData) {
            return count;
        }
        return 0;
    }

    /**
     * 将数据和时间点转换成整点开始的5分钟一个数据点的规则数据点列表
     *
     * @param time   : 时间轴
     * @param power  : 功率轴
     * @param energy : 能量轴
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author ycx
     * @date 2020/5/28
     */
    public static Map<String, Object> turnDataListToRegularTimeDataList(List<String> time, List<String> power, List<String> energy) {

        if (time == null || time.isEmpty() || power == null || power.isEmpty() || energy == null || energy.isEmpty()) {
            return null;
        }

        Map<String, Object> result = new HashMap<>();

        int hours = getHourBetweenTwoTime(time.get(0), time.get(time.size() - 1));
        int firstHour = Integer.parseInt(time.get(0).substring(0, 2));

        List<String> timeList = new ArrayList<>();
        List<String> powerList = MyTools.initList(hours * 12);
        List<String> energyList = MyTools.initList(hours * 12);

        //生成整点开始每5分钟一个点的规则之间列表
        for (int i = 0; i < hours; i++) {
            for (int j = 0; j < 12; j++) {
                timeList.add(MyTools.formatNum(firstHour + i) + ":" + MyTools.formatNum((j * 5)) + ":00");
            }
        }

        //将原始数据放入五分钟一个点的列表中
        for (int i = 0; i < time.size(); i++) {

            int index = (Integer.parseInt(time.get(i).substring(0, 2)) - firstHour) * 12 + Integer.parseInt(time.get(i).substring(3, 5)) / 5;
            powerList.set(index, AverageTwoString(powerList.get(index), power.get(i), 0));
            energyList.set(index, PlusTwoString(energyList.get(index), energy.get(i), 6));
        }

        result.put("time", timeList);
        result.put("power", powerList);
        result.put("energy", energyList);
        result.put("firstHour", firstHour);
        result.put("lastHour", firstHour + hours);

        return result;
    }


    /**
     * 将数据和时间点转换成整点开始的5分钟一个数据点的规则数据点列表
     *
     * @param time   : 时间轴
     * @param power  : 功率轴
     * @param energy : 能量轴
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author lym
     * @date 2021/01/13
     */
    public static Map<String, Object> turnDataListToRegularTimeDataList(List<String> time, List<String> power, List<String> energy, List<String> hourly) {

        if (time == null || time.isEmpty() || power == null || power.isEmpty() || energy == null || energy.isEmpty()) {
            return null;
        }

        Map<String, Object> result = new HashMap<>();

        int hours = getHourBetweenTwoTime(time.get(0), time.get(time.size() - 1));
        int firstHour = Integer.parseInt(time.get(0).substring(0, 2));

        List<String> timeList = new ArrayList<>();
        List<String> powerList = MyTools.initList(hours * 12);
        List<String> energyList = MyTools.initList(hours * 12);

        //生成整点开始每5分钟一个点的规则之间列表
        for (int i = 0; i < hours; i++) {
            for (int j = 0; j < 12; j++) {
                timeList.add(MyTools.formatNum(firstHour + i) + ":" + MyTools.formatNum((j * 5)) + ":00");
            }
        }

        //将原始数据放入五分钟一个点的列表中
        for (int i = 0; i < time.size(); i++) {

            int index = (Integer.parseInt(time.get(i).substring(0, 2)) - firstHour) * 12 + Integer.parseInt(time.get(i).substring(3, 5)) / 5;
            powerList.set(index, AverageTwoString(powerList.get(index), power.get(i), 0));
            energyList.set(index, PlusTwoString(energyList.get(index), energy.get(i), 6));
        }

        result.put("time", timeList);
        result.put("power", powerList);
        result.put("energy", energyList);
        result.put("hourly", hourly);
        result.put("firstHour", firstHour);
        result.put("lastHour", firstHour + hours);

        return result;
    }

    /**
     * 整合两个规则数据点列表
     *
     * @param dataMap1 : 数据1
     * @param dataMap2 : 数据2
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author ycx
     * @date 2020/5/28
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> mergeTwoRegularTimeDataList(Map<String, Object> dataMap1, Map<String, Object> dataMap2) {
        if (dataMap1 == null || dataMap1.isEmpty()) {
            return dataMap2;
        } else if (dataMap2 == null || dataMap2.isEmpty()) {
            return dataMap1;
        }

        //根据两个列表的时间来生成新的规则时间列表
        int firstHour1 = (int) dataMap1.get("firstHour");
        int firstHour2 = (int) dataMap2.get("firstHour");
        int firstHour = Math.min(firstHour1, firstHour2);
        int lastHour1 = (int) dataMap1.get("lastHour");
        int lastHour2 = (int) dataMap2.get("lastHour");
        int lastHour = Math.max(lastHour1, lastHour2);
        int hours = lastHour - firstHour + 1;

        List<String> timeList = new ArrayList<>();

        for (int i = 0; i < hours; i++) {
            for (int j = 0; j < 12; j++) {
                timeList.add(MyTools.formatNum(firstHour + i) + ":" + MyTools.formatNum((j * 5)) + ":00");
            }
        }

        //将两个格式的数据列表长度扩充至新规则列表的长度
        List<String> powerList1 = MyTools.initList(hours * 12);
        List<String> powerList2 = MyTools.initList(hours * 12);
        MyTools.replaceListByStart(powerList1, (List<String>) dataMap1.get("power"), (firstHour1 - firstHour) * 12);
        MyTools.replaceListByStart(powerList2, (List<String>) dataMap2.get("power"), (firstHour2 - firstHour) * 12);

        List<String> energyList1 = MyTools.initList(hours * 12);
        List<String> energyList2 = MyTools.initList(hours * 12);
        MyTools.replaceListByStart(energyList1, (List<String>) dataMap1.get("energy"), (firstHour1 - firstHour) * 12);
        MyTools.replaceListByStart(energyList2, (List<String>) dataMap2.get("energy"), (firstHour2 - firstHour) * 12);

        //合并两个数据列表
        Map<String, Object> result = new HashMap<>();
        result.put("time", timeList);
        result.put("power", SUMTwoStringList(powerList1, powerList2, 0));
        result.put("energy", SUMTwoStringList(energyList1, energyList2, 6));
        result.put("firstHour", firstHour);
        result.put("lastHour", firstHour + hours);

        if (dataMap1.get("hourly") != null) {
            result.put("hourly", SUMTwoStringList((List<String>) dataMap1.get("hourly"), (List<String>) dataMap2.get("hourly"), 6));
        }

        return result;
    }

    /**
     * 去除规则数据点列表中的空点
     *
     * @param dataMap : 数据
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author ycx
     * @date 2020/5/28
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> removeNullOrZeroInRegularTimeDataList(Map<String, Object> dataMap) {

        if (dataMap == null || dataMap.isEmpty()) {
            return null;
        }

        List<String> timeListTemp = (List<String>) dataMap.get("time");
        List<String> powerListTemp = (List<String>) dataMap.get("power");
        List<String> energyListTemp = (List<String>) dataMap.get("energy");

        List<String> timeList = new ArrayList<>();
        List<String> powerList = new ArrayList<>();
        List<String> energyList = new ArrayList<>();

        //去除数据列表中的空点（能量和功率都为空）
        for (int i = 0; i < timeListTemp.size(); i++) {
            if ((powerListTemp.get(i) != null && Double.parseDouble(powerListTemp.get(i)) > 0) ||
                    (energyListTemp.get(i) != null && Double.parseDouble(energyListTemp.get(i)) > 0)) {

                timeList.add(timeListTemp.get(i));
                powerList.add(powerListTemp.get(i));
                energyList.add(energyListTemp.get(i));
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("time", timeList);
        result.put("power", powerList);
        result.put("energy", energyList);
        result.put("firstHour", dataMap.get("firstHour"));
        result.put("lastHour", dataMap.get("lastHour"));

        return result;
    }


    /**
     * 计算同比
     *
     * @param data1 分子数据
     * @param data2 分母数据
     * @return
     */
    public static String calYOY(String data1, String data2) {
        if (data1 == null || data1.equals("") || data2 == null || data2.equals("")) {
            return null;
        }
        BigDecimal a1 = new BigDecimal(data1).setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(data2).setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.subtract(b1);
        a1 = a1.divide(b1, 4, BigDecimal.ROUND_HALF_UP);
        a1 = a1.multiply(new BigDecimal(100));
        return String.valueOf(a1.doubleValue());
    }

    /**
     * 计算占比
     *
     * @param data1 分子数据
     * @param data2 分母数据
     * @return
     */
    public static String calShare(String data1, String data2) {
        if (data1 == null || data1.equals("") || data2 == null || data2.equals("")) {
            return null;
        }
        BigDecimal a1 = new BigDecimal(data1).setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal b1 = new BigDecimal(data2).setScale(6, BigDecimal.ROUND_HALF_UP);
        a1 = a1.divide(b1, 4, BigDecimal.ROUND_HALF_UP);
        a1 = a1.multiply(new BigDecimal(100));
        return String.valueOf(a1.doubleValue());
    }

    /**
     * 将全年每天的发电数据 转换成为全年每礼拜的发电数据
     *
     * @param energyList 全年每天的发电数据
     * @param weekNum    取前几周
     * @return
     */
    public static List<String> ChangeEveryDayEnergyToWeekEnergy(List<String> energyList, int weekNum) {
        //循环处理数据
        List<String> result = new ArrayList<String>();
        for (int i = 0; i < weekNum; i++) {
            String totalEnergy = null;
            for (int j = i * 7; j < (i * 7 + 7); j++) {
                if (j < energyList.size()) {
                    totalEnergy = PlusTwoStringParam(totalEnergy, energyList.get(j));
                }
            }
            result.add(totalEnergy);
        }
        return result;
    }

    /**
     * 将Double类型数据转换成字符串 并且保留num位小数位小数
     *
     * @param data Double
     * @return java.lang.String
     * @author ycx
     * @date 2020/12/23
     */
    public static String FormatDoubleToString(Double data, int num) {

        return String.valueOf(new BigDecimal(data).setScale(num, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 保留小数位
     *
     * @param data : 数据
     * @param num  : 小数位数
     * @return java.lang.String
     * @author ycx
     * @date 2021/1/19
     */
    public static String FormatStringDecimal(String data, int num) {

        return new BigDecimal(data).setScale(num, BigDecimal.ROUND_HALF_UP).toPlainString();
    }

    /**
     * 将FLoat数据转换为String并保留num位小数
     *
     * @param num   数据
     * @param scale 保留位数
     * @return java.lang.String
     * @author ycx
     * @date 2023/3/3
     */
    public static String FormatFloatToString(Float num, int scale) {
        if (num == null) {
            return null;
        }
        return String.valueOf(new BigDecimal(num).setScale(scale, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 列表求和
     *
     * @param list  列表
     * @param scale 保留小数位
     * @return java.lang.String
     * @author ycx
     * @date 2023/3/4
     */
    public static String SUMList(List<String> list, int scale) {
        if (list == null) {
            return null;
        }
        String sum = null;
        for (String child : list) {
            sum = PlusTwoString(sum, child, scale);
        }
        return sum;
    }

    /**
     * 列表求平均
     *
     * @param list  列表
     * @param scale 保留小数位
     * @return java.lang.String
     * @author ycx
     * @date 2023/3/4
     */
    public static String AverageList(List<String> list, int scale) {
        if (list == null) {
            return null;
        }
        String sum = null;
        for (String child : list) {
            sum = PlusTwoString(sum, child, scale);
        }
        return DivideTwoString(sum, Integer.toString(CountNotNull(list)), 6);
    }

    /**
     * 获取环保收益——新
     *
     * @param energy 发电量
     * @return java.util.Map<java.lang.String, java.lang.String>
     * @author ycx
     * @date 2023/4/7
     */
    public static Map<String, String> GetEnvironmentalProtectionNew(String energy) {
        if (energy == null) {
            return null;
        }
        Map<String, String> envPro = new HashMap<>();
        envPro.put("co2", MultiplyTwoString(energy, "0.997", 6));
        envPro.put("tree", DivideTwoString(energy, "27.2", 6));
        envPro.put("carbon", MultiplyTwoString(energy, "0.4", 6));
        return envPro;
    }
}
